/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.unal.bioingenium.kbmed.knowledge.mapping.heuristic;

import co.edu.unal.bioingenium.kbmed.knowledge.mapping.vo.DescriptorScore;

/**
 *
 * @author Luis A Riveros
 */
public class MatchingFunctions {

    /**
     * 
     * @param descriptorScore
     * @return
     */
    public static double getMean(DescriptorScore descriptorScore) {
        double[] scores = descriptorScore.getScores();
        short[] positions = descriptorScore.getPositions();
        double mean = 0;
        short termMatchingCount = 1;
        for (int i = 0; i < positions.length; i++) {
            if (positions[i] != -1) {
                mean += scores[i];
                termMatchingCount++;
            }
        }
        return mean / (double) termMatchingCount;
    }

    /**
     * 
     * @param descriptorScore
     * @return
     */
    public static double getCoverage(DescriptorScore descriptorScore) {
        short termMatchingCount = 0;
        short[] positions = descriptorScore.getPositions();
        for (int i = 0; i < positions.length; i++) {
            if (positions[i] != -1) {
                termMatchingCount++;
            }
        }
        return (double) termMatchingCount / ((double) descriptorScore.getDescriptorTokens());// * (double) positions.length / 2);
    }

    /**
     * 
     * @param descriptorScore
     * @return
     */
    public static double getCohesiveness(DescriptorScore descriptorScore) {
        int connectedComponentsCount = 1;
        int connectedComponentsLength = 0;
        int tempLength;
        short[] positions = descriptorScore.getPositions();
        if (positions.length > 1) {
            for (int i = 1; i < positions.length; i++) {
                tempLength = 1;
                while (i < positions.length && (Math.abs(positions[i] - positions[i - 1])) < 2) {
                    tempLength++;
                    i++;
                }
                if (tempLength > 1) {
                    connectedComponentsCount++;
                    connectedComponentsLength += tempLength;
                }
            }
        } else {
            if (positions[0] >= 0) {
                connectedComponentsLength = 1;
            }
        }
        return ((double) connectedComponentsLength / (double) positions.length) / (double) connectedComponentsCount;
    }

    /**
     * 
     * @param descriptorScore
     * @param maxValues
     * @return
     */
    public static double function(DescriptorScore descriptorScore, double[] maxValues) {
        double[] scores = descriptorScore.getScores();
        short[] positions = descriptorScore.getPositions();
        double matchMean = 0;
        double scaledMean = 0;
        double dist = 0;
        int matchCount = 0;
        for (int i = 0; i < positions.length; i++) {
            if (positions[i] != -1) {
                scaledMean += scores[i] / maxValues[i];
                matchMean += scores[i];
                matchCount++;
                dist += i + 1;
            }
        }
        scaledMean = scaledMean / (double) matchCount;
        matchMean = matchMean / (double) matchCount;
        dist = dist / (double) positions.length;
        return (0.25 * (matchMean) + 
                0.25 * (1 / (double) matchCount) + 
                0.25 * (scaledMean) + 
                0.25 * (1 / (dist + 1))) * 
                ((double) matchCount / (double) descriptorScore.getDescriptorTokens());
    }


    /**
     * 
     * @param scores
     */
    public static void printScores(double[] scores) {
        for (int i = 0; i < scores.length; i++) {
            System.out.print(" " + scores[i]);
        }
        System.out.println(" ");
    }

    /**
     * 
     * @param args
     */
    public static void main(String[] args) {
        double[][] sco = {{0.9, 0, 0}, {0.7, 0.7, 0}, {0.7, 0, 0.7}, {0.6, 0.7, 0}, {0.7, 0.6, 0}};
        short[][] pos = {{1, -1, -1}, {1, 1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, -1}};

        double[] max = {0.9, 0.7, 0.7};
        for (int i = 0; i < 5; i++) {
//            System.out.println(function(sco[i], pos[i], max));


        }



    }
}
